/*
 * Copyright (c) 2010-2020 Belledonne Communications SARL.
 *
 * This file is part of linphone-android
 * (see https://www.linphone.org).
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.newlink.building.activities.main.settings.viewmodels

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.newlink.building.NL_App.Companion.coreContext
import com.newlink.building.NL_App.Companion.corePreferences
import com.newlink.building.activities.main.settings.Module_Phone_SettingListenerStub
import com.newlink.building.utils.Module_Phone_Event
import org.linphone.core.*
import org.linphone.core.tools.Log

class Module_Phone_SettingsViewModel : ViewModel() {
    private val tunnelAvailable: Boolean = coreContext.core.tunnelAvailable()

    val showAccountSettings: Boolean = corePreferences.showAccountSettings
    val showTunnelSettings: Boolean = tunnelAvailable && corePreferences.showTunnelSettings
    val showAudioSettings: Boolean = corePreferences.showAudioSettings
    val showVideoSettings: Boolean = corePreferences.showVideoSettings
    val showCallSettings: Boolean = corePreferences.showCallSettings
    val showChatSettings: Boolean = corePreferences.showChatSettings
    val showNetworkSettings: Boolean = corePreferences.showNetworkSettings
    val showContactsSettings: Boolean = corePreferences.showContactsSettings
    val showAdvancedSettings: Boolean = corePreferences.showAdvancedSettings

    val accounts = MutableLiveData<ArrayList<AccountSettingsViewModel>>()

    private var accountClickListener = object : Module_Phone_SettingListenerStub() {
        override fun onAccountClicked(identity: String) {
            accountsSettingsListener.onAccountClicked(identity)
        }
    }

    lateinit var accountsSettingsListener: Module_Phone_SettingListenerStub

    lateinit var tunnelSettingsListener: Module_Phone_SettingListenerStub

    lateinit var audioSettingsListener: Module_Phone_SettingListenerStub

    lateinit var videoSettingsListener: Module_Phone_SettingListenerStub

    lateinit var callSettingsListener: Module_Phone_SettingListenerStub

    lateinit var chatSettingsListener: Module_Phone_SettingListenerStub

    lateinit var networkSettingsListener: Module_Phone_SettingListenerStub

    lateinit var logSettingsListener: Module_Phone_SettingListenerStub

    lateinit var logoutListener: Module_Phone_SettingListenerStub

    lateinit var aboutSettingsListener: Module_Phone_SettingListenerStub

    lateinit var contactsSettingsListener: Module_Phone_SettingListenerStub

    lateinit var advancedSettingsListener: Module_Phone_SettingListenerStub

    lateinit var logoutSettingsListener: Module_Phone_SettingListenerStub

    val settingsRemovedEvent: MutableLiveData<Module_Phone_Event<Boolean>> = MutableLiveData<Module_Phone_Event<Boolean>>()

    val waitForUnregister = MutableLiveData<Boolean>()

    val primaryAccountDisplayNameListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            val address = coreContext.core.createPrimaryContactParsed()
            address ?: return
            address.displayName = newValue
            address.username = primaryAccountUsername.value
            coreContext.core.primaryContact = address.asString()

            primaryAccountDisplayName.value = newValue
        }
    }
    val primaryAccountDisplayName = MutableLiveData<String>()

    val primaryAccountUsernameListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            val address = coreContext.core.createPrimaryContactParsed()
            address ?: return
            address.username = newValue
            address.displayName = primaryAccountDisplayName.value
            coreContext.core.primaryContact = address.asString()

            primaryAccountUsername.value = newValue
        }
    }
    val primaryAccountUsername = MutableLiveData<String>()

    private var accountToDelete: Account? = null

    val listener: AccountListenerStub = object : AccountListenerStub() {
        override fun onRegistrationStateChanged(
            account: Account,
            state: RegistrationState,
            message: String
        ) {
            Log.e("[Account Settings]  ****    onRegistrationStateChanged  ${state.name}")
            if (state == RegistrationState.Cleared && account == accountToDelete) {
                Log.i("[Account Settings] Account to remove registration is now cleared")
                deleteAccount(account)
                waitForUnregister.value = false
            }
        }
    }

    init {
        updateAccountsList()
        coreContext.core.defaultAccount?.addListener(listener)

        val address = coreContext.core.createPrimaryContactParsed()
        primaryAccountDisplayName.value = address?.displayName ?: ""
        primaryAccountUsername.value = address?.username ?: ""
    }

    override fun onCleared() {
        accounts.value.orEmpty().forEach(AccountSettingsViewModel::destroy)
        coreContext.core.defaultAccount?.removeListener(listener)
        super.onCleared()
    }

    fun updateAccountsList() {
        accounts.value.orEmpty().forEach(AccountSettingsViewModel::destroy)

        val list = arrayListOf<AccountSettingsViewModel>()
        if (coreContext.core.accountList.isNotEmpty()) {
            for (account in coreContext.core.accountList) {
                val viewModel = AccountSettingsViewModel(account)
                viewModel.accountsSettingsListener = accountClickListener
                list.add(viewModel)
            }
        }

        accounts.value = list
    }

    fun deleteAccount() {
        val account = coreContext.core.defaultAccount
//        deleteDefaultAccount(account!!)
        if (account != null) {
            val registered = account.state == RegistrationState.Ok
            waitForUnregister.value = registered
            accountToDelete = account
            val params = account.params.clone()
            params.isRegisterEnabled = false
            account.params = params

            if (!registered) {
                Log.w("[Account Settings] Account isn't registered, don't unregister before removing it")
                deleteAccount(account)
            }
        }
    }

    fun clearRecordsAndHistory() {

//        GlobalScope.launch {
//            LinPhoneApp.contactRepository.deleteAllRelay()
//            LinPhoneApp.contactRepository.deleteAllContact()
//        }

        coreContext.core.clearCallLogs()
    }

    private fun deleteDefaultAccount(account: Account) {
        val authInfo = account.findAuthInfo()
        if (authInfo != null) {
            Log.i("[Account Settings] Found auth info $authInfo, removing it.")
            coreContext.core.removeAuthInfo(authInfo)
        } else {
            Log.w("[Account Settings] Couldn't find matching auth info...")
        }

        coreContext.core.removeAccount(account)
        settingsRemovedEvent.value = Module_Phone_Event(true)
    }

    private fun deleteAccount(account: Account) {
        Log.e("[Account Settings]   deleteAccount")
        val authInfo = account.findAuthInfo()
        if (authInfo != null) {
            Log.i("[Account Settings] Found auth info $authInfo, removing it.")
            coreContext.core.removeAuthInfo(authInfo)
        } else {
            Log.w("[Account Settings] Couldn't find matching auth info...")
        }

        coreContext.core.removeAccount(account)
        corePreferences.firstStart = true
        settingsRemovedEvent.value = Module_Phone_Event(true)
    }
//    val logoutListener = object : SettingListenerStub() {
//        override fun onClicked() {
//            accounts.value.orEmpty().forEach(AccountSettingsViewModel::destroy)
//            context.startActivity(Intent(context, LoginActivity::class.java))
//        }
//    }
}
